<template>
    <div class="designer-container">
      <!-- 左侧节点面板 -->
      <NodePalette 
        :nodeTypes="nodeTypeList" 
        @dragstart="onDragStart"
      />
      
      <div class="designer-canvas" tabindex="0" @keydown.delete="handleDelete" @keydown.backspace="handleDelete">
        <VueFlow
          v-model:nodes="nodes"
          v-model:edges="edges"
          :fit-view="true"
          :min-zoom="0.2"
          :max-zoom="2"
          :node-types="nodeTypes"
          :connection-mode="ConnectionMode.Loose"
          :snap-to-grid="true"
          :snap-grid="[15, 15]"
          class="vue-flow-canvas"
          @drop="onDrop"
          @dragover.prevent
          @connect="onConnect"
          @node-click="onNodeClick"
          @edge-click="onEdgeClick"
        >
          <Background />
          <MiniMap />
          <Controls />
        </VueFlow>
      </div>
      
      <div class="designer-actions">
        <el-button type="primary" @click="onSave">保存</el-button>
        <el-button @click="goBack">返回</el-button>
      </div>
      
      <!-- 右侧属性面板 -->
      <PropertyPanel
        v-if="selectedNode || selectedEdge"
        :selectedNode="selectedNode"
        :selectedEdge="selectedEdge"
        :propertyPanel="propertyPanel"
        :propertyPanelWidth="propertyPanelWidth"
        @property-change="onPropertyChange"
        @edge-property-change="onEdgePropertyChange"
        @close="closePanel"
        @delete="handleDelete"
        @resize="startResize"
        @open-selector="onOpenSelector"
      />
    </div>
    
    <SelectorModal
      :type="selectorType"
      :visible="selectorVisible"
      :multiple="selectorMultiple"
      :selectedList="selectorSelected"
      @update:visible="val => selectorVisible = val"
      @update:selectedList="handleSelectorUpdate"
      @close="selectorVisible = false"
    ></SelectorModal>
  </template>
  <script setup>
  import { ref, onMounted, reactive, computed } from 'vue'
  import { useRoute, useRouter } from 'vue-router'
  import { ElMessage } from 'element-plus'
  import { VueFlow, useVueFlow, addEdge, ConnectionMode } from '@vue-flow/core'
  import { Background, MiniMap, Controls } from '@vue-flow/additional-components'
  import '@vue-flow/core/dist/style.css'
  import '@vue-flow/core/dist/theme-default.css'
  import { getProcessDetail, editProcess } from '@/api/workflow/process.api'
  import SelectorModal from '@/components/Selector/SelectorModal.vue'
  import NodePalette from './components/NodePalette.vue'
  import PropertyPanel from './components/PropertyPanel.vue'
  import { GatewayNode, EventNode, TaskNode, UserTaskNode, CcNode, SubProcessNode } from './components/CustomNodes.js'
  
  // 引入样式文件
  import './styles/process-designer.css'
  import './styles/property-panel.css'

  // 引入统一的夜间模式样式
  import '@/components/Workflow/styles/dark-theme.css'

  const selectorVisible = ref(false)
  const selectorType = ref('role')
  const selectorSelected = ref([])
  const selectorIdx = ref(-1)
  const selectorMultiple = ref(true)
  const isCcSelector = ref(false) // 新增：标识是否是抄送选择器
  
  // 处理选择器打开
  function onOpenSelector(data) {
    console.log('process-designer - onOpenSelector called with data:', data)
    
    const { idx, type, isCc } = data
    selectorIdx.value = idx
    selectorType.value = type
    selectorMultiple.value = true
    isCcSelector.value = isCc || false
    
    // 根据是否是抄送配置来设置选中的数据
    if (isCc) {
      // 抄送配置
      selectorSelected.value = propertyPanel.cc[idx]?.value || []
    } else {
      // 人员配置
      selectorSelected.value = propertyPanel.assignees[idx]?.value || []
    }
    
    console.log('process-designer - setting selectorVisible to true')
    selectorVisible.value = true
  }

  function handleSelectorUpdate(list) {
    console.log('process-designer - handleSelectorUpdate called with list:', list)
    console.log('process-designer - selectorIdx:', selectorIdx.value, 'selectorType:', selectorType.value, 'isCc:', isCcSelector.value)
    
    if (selectorIdx.value >= 0) {
      // 根据选择器类型进行不同的数据映射
      let mappedData
      if (selectorType.value === 'user') {
        mappedData = list.map(u => ({
          id: u.id,
          userName: u.userName,
          nickName: u.nickName,
          avatar: u.avatar,
          posts: u.posts,
        }))
      } else if (selectorType.value === 'role') {
        mappedData = list.map(r => ({
          id: r.id,
          name: r.name,
          code: r.code,
        }))
      } else if (selectorType.value === 'dept') {
        mappedData = list.map(d => ({
          id: d.id,
          name: d.name,
          code: d.code,
        }))
      } else if (selectorType.value === 'post') {
        mappedData = list.map(p => ({
          id: p.id,
          name: p.name,
          code: p.code,
        }))
      } else {
        // 默认处理，保留原始数据
        mappedData = list
      }
      
      if (isCcSelector.value) {
        // 更新抄送配置
        if (!propertyPanel.cc[selectorIdx.value]) {
          propertyPanel.cc[selectorIdx.value] = { type: selectorType.value, value: [] }
        }
        propertyPanel.cc[selectorIdx.value].value = mappedData
      } else {
        // 更新人员配置
        if (!propertyPanel.assignees[selectorIdx.value]) {
          propertyPanel.assignees[selectorIdx.value] = { type: selectorType.value, value: [] }
        }
        propertyPanel.assignees[selectorIdx.value].value = mappedData
      }
      
      onPropertyChange()
    }
  }
  
  function getAssigneeTypeLabel(type) {
    switch(type) {
      case 'starter': return '发起人';
      case 'starterDeptLeader': return '发起人部门负责人';
      case 'starterDeptParentLeader': return '发起人上级部门负责人';
      default: return type;
    }
  }

  const route = useRoute()
  const router = useRouter()
  const { addNodes } = useVueFlow()

  // 自定义节点类型注册
  const nodeTypes = {
    gateway: GatewayNode,
    event: EventNode,
    task: TaskNode,
    userTask: UserTaskNode,
    cc: CcNode,
    subProcess: SubProcessNode
  }

  // 节点类型定义
  const nodeTypeList = [
    { type: 'start', label: '开始', color: '#52c41a', nodeType: 'event', eventType: 'start' },
    { type: 'userTask', label: '用户任务', color: '#1890ff', nodeType: 'userTask' },
    { type: 'task', label: '任务', color: '#722ed1', nodeType: 'task' },
    { type: 'gateway', label: '网关', color: '#faad14', nodeType: 'gateway', gatewayType: 'exclusive' },
    { type: 'cc', label: '抄送', color: '#13c2c2', nodeType: 'cc' },
    { type: 'subProcess', label: '子流程', color: '#eb2f96', nodeType: 'subProcess' },
    { type: 'end', label: '结束', color: '#f5222d', nodeType: 'event', eventType: 'end' }
  ]

  const selectedNodeId = ref(null)
  const selectedEdgeId = ref(null)
  const propertyPanel = reactive({
    id: '',
    name: '',
    type: '',
    priority: 50, // 新增：任务优先级，默认为普通
    assignees: [], // [{type: 'role', value: ''}]
    countersign: { 
      type: '', 
      loopDataInputRef: 'assigneeList',
      customVariableName: '',
      completionType: 'all',
      minPass: null, 
      maxPass: null,
      percentage: 50
    },
    listeners: [], // [{event: '', type: '', class: ''}]
    cc: [], // 抄送人员
    notifyMethods: [], // 抄送推送方式
    advanced: { 
      pcFormUrl: '', 
      mobileFormUrl: '', 
      timeout: null,
      // 移除人员设置优先级控制，保留人员编辑权限控制
      personnelEditPermission: 'full' // 人员编辑权限控制
    },
    nodeStyle: {}, // 新增节点样式
    lineStyle: {} // 新增连线样式
  })

  const originalPanelData = ref(null)

  // 计算属性：当前选中节点/连线对象
  const selectedNode = computed(() => nodes.value.find(n => n.id === selectedNodeId.value))
  const selectedEdge = computed(() => edges.value.find(e => e.id === selectedEdgeId.value))

  const nodes = ref([
    {
      id: 'start',
      type: 'event',
      position: { x: 100, y: 100 },
      data: { 
        label: '开始',
        eventType: 'start',
        nodeStyle: {
          background: '#52c41a',
          color: '#fff',
          border: '2px solid #389e0d'
        }
      }
    }
  ])
  const edges = ref([])

  const processId = route.query.id
  const processMeta = ref({})

  onMounted(async () => {
    console.log(processId);

    if (processId) {
      const res = await getProcessDetail(processId)
      if (res && res) {
        processMeta.value = { ...res }
        if (res.graphSchema) {
          try {
            const graph = JSON.parse(res.graphSchema)
            nodes.value = graph.nodes || []
            edges.value = graph.edges || []
          } catch (e) {
            console.error('解析流程数据失败:', e)
            // 解析失败，忽略
          }
        }
      }
    }
  })

  function onDragStart(item, event) {
    event.dataTransfer.setData('application/vueflow', JSON.stringify(item))
    event.dataTransfer.effectAllowed = 'move'
  }
  function onDrop(event) {
    const data = event.dataTransfer.getData('application/vueflow')
    if (!data) return
    
    const item = JSON.parse(data)
    const bounds = event.target.getBoundingClientRect()
    const position = {
      x: event.clientX - bounds.left,
      y: event.clientY - bounds.top
    }
    const id = `${item.type}_${Date.now()}`
    
    // 构建节点数据
    const nodeData = {
      label: item.label
    }
    
    // 根据节点类型添加特定属性
    if (item.nodeType === 'event') {
      nodeData.eventType = item.eventType
    } else if (item.nodeType === 'gateway') {
      nodeData.gatewayType = item.gatewayType || 'exclusive'
    } else if (item.nodeType === 'task') {
      nodeData.taskType = 'task'
    }
    
    // 直接使用nodeType作为VueFlow类型
    const vueFlowType = item.nodeType
    
    addNodes([{
      id,
      type: vueFlowType,
      position,
      data: nodeData
    }])
  }
  function onConnect(params) {
    edges.value = addEdge(params, edges.value)
  }
  async function onSave() {
    if (!processId) {
      ElMessage.error('未获取到流程ID，无法保存')
      return
    }
    
    // 直接保存VueFlow格式
    const graphSchema = {
      nodes: nodes.value,
      edges: edges.value
    }
    const data = { ...processMeta.value, graphSchema: JSON.stringify(graphSchema), id: processId }
    await editProcess(data)
    ElMessage.success('流程设计已保存')
  }

  function goBack() {
    router.back()
  }

  // 选中节点
  function onNodeClick(e) {
    const node = e?.node || e
    selectedNodeId.value = node.id
    selectedEdgeId.value = null
    // 回显属性
    propertyPanel.id = node.id
    propertyPanel.name = node.data?.label || ''
    propertyPanel.type = node.type
    propertyPanel.priority = node.data?.priority || 50 // 回显优先级
    propertyPanel.assignees = node.data?.assignees || []
    propertyPanel.countersign = {
      type: node.data?.countersign?.type || '',
      loopDataInputRef: node.data?.countersign?.loopDataInputRef || 'assigneeList',
      customVariableName: node.data?.countersign?.customVariableName || '',
      completionType: node.data?.countersign?.completionType || 'all',
      minPass: node.data?.countersign?.minPass || null,
      maxPass: node.data?.countersign?.maxPass || null,
      percentage: node.data?.countersign?.percentage || 50
    }
    propertyPanel.listeners = node.data?.listeners || []
    propertyPanel.cc = node.data?.cc || []
    propertyPanel.notifyMethods = node.data?.notifyMethods || [] // 回显抄送推送方式
    propertyPanel.advanced = node.data?.advanced || { 
      pcFormUrl: '', 
      mobileFormUrl: '', 
      timeout: null,
      personnelEditPermission: 'full'
    }
    // 确保节点样式是独立的副本
    propertyPanel.nodeStyle = node.data?.nodeStyle ? { ...node.data.nodeStyle } : {} // 回显节点样式
    // 记录原始数据
    originalPanelData.value = JSON.parse(JSON.stringify(propertyPanel))
  }
  // 选中连线
  function onEdgeClick(e) {
    const edge = e?.edge || e
    selectedEdgeId.value = edge.id
    selectedNodeId.value = null
    // 回显属性
    propertyPanel.id = edge.id
    propertyPanel.label = edge.label || ''
    
    // 回显连线条件配置
    propertyPanel.conditionType = edge.conditionType || ''
    propertyPanel.conditionExpression = edge.conditionExpression || ''
    propertyPanel.scriptLanguage = edge.scriptLanguage || 'javascript'
    propertyPanel.scriptContent = edge.scriptContent || ''
    
    // 回显连线样式 - 将VueFlow样式格式转换为LineStyleConfig期望的格式
    const edgeStyle = edge.style || {}
    propertyPanel.lineStyle = {
      stroke: edgeStyle.stroke || '#b1b1b7',
      strokeWidth: edgeStyle.strokeWidth || 3,
      lineType: edge.type || 'smoothstep',
      dashed: !!edgeStyle.strokeDasharray,
      dashArray: edgeStyle.strokeDasharray || '5,5',
      animated: !!edge.animated,
      animationSpeed: parseInt(edgeStyle.animationDuration) || 5,
      label: edge.label || '',
      labelPosition: 'middle',
      labelColor: edge.labelStyle?.fill || '#333333',
      labelSize: edge.labelStyle?.fontSize || 12
    }
    
    // 记录原始数据
    originalPanelData.value = { 
      id: edge.id, 
      label: edge.label || '', 
      conditionType: edge.conditionType || '',
      conditionExpression: edge.conditionExpression || '',
      scriptLanguage: edge.scriptLanguage || 'javascript',
      scriptContent: edge.scriptContent || '',
      lineStyle: { ...propertyPanel.lineStyle }
    }
  }

  // 删除选中节点或连线
  function handleDelete() {
    if (selectedNodeId.value) {
      // 删除节点及相关连线
      nodes.value = nodes.value.filter(n => n.id !== selectedNodeId.value)
      edges.value = edges.value.filter(e => e.source !== selectedNodeId.value && e.target !== selectedNodeId.value)
      selectedNodeId.value = null
    } else if (selectedEdgeId.value) {
      // 删除连线
      edges.value = edges.value.filter(e => e.id !== selectedEdgeId.value)
      selectedEdgeId.value = null
    }
  }

  // 连线属性变更
  function onEdgePropertyChange() {
    const edge = edges.value.find(e => e.id === selectedEdgeId.value)
    if (edge) {
      edge.label = propertyPanel.label
      
      // 保存连线条件配置
      if (propertyPanel.conditionType) {
        edge.conditionType = propertyPanel.conditionType
        edge.conditionExpression = propertyPanel.conditionExpression
        edge.scriptLanguage = propertyPanel.scriptLanguage
        edge.scriptContent = propertyPanel.scriptContent
      }
      
      // 应用连线样式
      if (propertyPanel.lineStyle) {
        // 更新edge.style
        edge.style = {
          ...edge.style,
          stroke: propertyPanel.lineStyle.stroke,
          strokeWidth: propertyPanel.lineStyle.strokeWidth,
          strokeDasharray: propertyPanel.lineStyle.dashed ? propertyPanel.lineStyle.dashArray : undefined
        }
        
        // 设置连线类型
        if (propertyPanel.lineStyle.lineType) {
          edge.type = propertyPanel.lineStyle.lineType
        }
        
        // 设置动画
        if (propertyPanel.lineStyle.animated) {
          edge.animated = true
          edge.style.animationDuration = propertyPanel.lineStyle.animationSpeed + 's'
        } else {
          edge.animated = false
          delete edge.style.animationDuration
        }
        
        // 设置标签样式
        if (propertyPanel.lineStyle.label) {
          edge.label = propertyPanel.lineStyle.label
        }
        
        // 更新标签样式
        edge.labelStyle = {
          ...edge.labelStyle,
          fill: propertyPanel.lineStyle.labelColor,
          fontSize: propertyPanel.lineStyle.labelSize
        }
      }
    }
  }

  function onPropertyChange() {
    const node = nodes.value.find(n => n.id === selectedNodeId.value)
    if (node) {
      node.data = {
        ...node.data,
        label: propertyPanel.name,
        priority: propertyPanel.priority, // 保存优先级
        assignees: propertyPanel.assignees,
        countersign: propertyPanel.countersign,
        listeners: propertyPanel.listeners,
        cc: propertyPanel.cc,
        notifyMethods: propertyPanel.notifyMethods, // 添加抄送推送方式
        advanced: propertyPanel.advanced,
        nodeStyle: propertyPanel.nodeStyle ? { ...propertyPanel.nodeStyle } : {} // 确保节点样式是独立的副本
      }
      
      // 样式现在通过Vue响应式系统自动应用，不需要手动DOM操作
    }
  }

  // 保存按钮逻辑
  function handlePanelSave() {
    if (selectedNodeId.value) {
      onPropertyChange()
      selectedNodeId.value = null
    } else if (selectedEdgeId.value) {
      onEdgePropertyChange()
      selectedEdgeId.value = null
    }
  }
  // 取消按钮逻辑
  function handlePanelCancel() {
    if (selectedNodeId.value && originalPanelData.value) {
      // 恢复节点属性
      const node = nodes.value.find(n => n.id === selectedNodeId.value)
      if (node) {
        node.data = {
          ...node.data,
          label: originalPanelData.value.name,
          priority: originalPanelData.value.priority, // 恢复优先级
          assignees: originalPanelData.value.assignees,
          countersign: originalPanelData.value.countersign,
          listeners: originalPanelData.value.listeners,
          cc: originalPanelData.value.cc,
          notifyMethods: originalPanelData.value.notifyMethods, // 恢复抄送推送方式
          advanced: originalPanelData.value.advanced,
          nodeStyle: originalPanelData.value.nodeStyle ? { ...originalPanelData.value.nodeStyle } : {} // 恢复节点样式，确保是独立副本
        }
      }
      selectedNodeId.value = null
    } else if (selectedEdgeId.value && originalPanelData.value) {
      // 恢复连线属性
      const edge = edges.value.find(e => e.id === selectedEdgeId.value)
      if (edge) {
        edge.label = originalPanelData.value.label
        // 恢复连线条件配置
        if (originalPanelData.value.conditionType) {
          edge.conditionType = originalPanelData.value.conditionType
          edge.conditionExpression = originalPanelData.value.conditionExpression
          edge.scriptLanguage = originalPanelData.value.scriptLanguage
          edge.scriptContent = originalPanelData.value.scriptContent
        }
        // 恢复连线样式
        if (originalPanelData.value.lineStyle) {
          edge.style = {
            stroke: originalPanelData.value.lineStyle.stroke,
            strokeWidth: originalPanelData.value.lineStyle.strokeWidth,
            strokeDasharray: originalPanelData.value.lineStyle.dashed ? originalPanelData.value.lineStyle.dashArray : undefined
          }
          
          // 恢复连线类型
          if (originalPanelData.value.lineStyle.lineType) {
            edge.type = originalPanelData.value.lineStyle.lineType
          }
          
          // 恢复动画
          if (originalPanelData.value.lineStyle.animated) {
            edge.animated = true
            edge.style.animationDuration = originalPanelData.value.lineStyle.animationSpeed + 's'
          } else {
            edge.animated = false
            delete edge.style.animationDuration
          }
          
          // 恢复标签样式
          edge.labelStyle = {
            fill: originalPanelData.value.lineStyle.labelColor,
            fontSize: originalPanelData.value.lineStyle.labelSize
          }
        }
      }
      selectedEdgeId.value = null
    }
  }

  function closePanel() {
    selectedNodeId.value = null
    selectedEdgeId.value = null
  }

  const propertyPanelWidth = ref(700)
  let resizing = false
  let startX = 0
  let startWidth = 0
  function startResize(e) {
    resizing = true
    startX = e.clientX
    startWidth = propertyPanelWidth.value
    document.body.style.cursor = 'col-resize'
    document.addEventListener('mousemove', onResizing)
    document.addEventListener('mouseup', stopResize)
  }
  function onResizing(e) {
    if (!resizing) return
    const delta = startX - e.clientX
    let newWidth = startWidth + delta
    if (newWidth < 320) newWidth = 320
    if (newWidth > 800) newWidth = 800
    propertyPanelWidth.value = newWidth
  }
  function stopResize() {
    resizing = false
    document.body.style.cursor = ''
    document.removeEventListener('mousemove', onResizing)
    document.removeEventListener('mouseup', stopResize)
  }
  </script>
  <style scoped>
  .designer-container {
    display: flex;
    height: 90vh;
    position: relative;
  }
  .designer-sidebar {
    width: 120px;
    background: #f5f5f5;
    border-right: 1px solid #eee;
    padding: 16px 0;
  }
  .designer-toolbox {
    display: flex;
    flex-direction: column;
    gap: 16px;
  }
  .tool-item {
    display: flex;
    align-items: center;
    cursor: grab;
    padding: 8px 12px;
    background: #fff;
    border-radius: 4px;
    border: 1px solid #e0e0e0;
    user-select: none;
  }
  .tool-icon {
    display: inline-block;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    margin-right: 8px;
  }
  .designer-canvas {
    flex: 1;
    min-width: 0;
    background: #fff;
    position: relative;
  }
  .vue-flow-canvas {
    width: 100%;
    height: 100%;
  }
  .designer-actions {
    position: fixed;
    right: 40px;
    bottom: 40px;
    z-index: 100;
    display: flex;
    gap: 12px;
  }
  .designer-property-panel {
    position: absolute;
    top: 0;
    right: 0;
    width: 420px;
    height: 100%;
    background: #fafbfc;
    border-left: 1px solid #eee;
    padding: 16px;
    overflow-y: auto;
    z-index: 20;
    transition: width 0.15s;
    box-sizing: border-box;
    min-width: 320px;
    max-width: 800px;
    display: flex;
    flex-direction: column;
  }
  .panel-resizer {
    position: absolute;
    left: 0;
    top: 0;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    background: transparent;
    z-index: 30;
    transition: background 0.2s;
  }
  .panel-resizer:hover {
    background: #e4e7ed44;
  }
  .panel-footer {
    position: sticky;
    bottom: 0;
    background: #fafbfc;
    padding: 16px 0 0 0;
    display: flex;
    gap: 12px;
    border-top: 1px solid #eee;
    z-index: 2;
  }
  .panel-close-btn {
    position: absolute;
    top: 20px;
    right: 20px;
    z-index: 10;
    padding: 0;
    min-width: 32px;
    min-height: 32px;
    color: #909399;
    background: transparent;
    border-radius: 50%;
    transition: background 0.2s, color 0.2s;
  }
  .panel-close-btn:hover {
    background: #f56c6c22;
    color: #f56c6c;
  }
  .close-x {
    font-size: 24px;
    font-weight: bold;
    line-height: 1;
    display: inline-block;
    color: inherit;
  }
  .main-info-block {
    background: #f5f7fa;
    border-radius: 8px;
    padding: 18px 12px 12px 12px;
    margin-bottom: 18px;
  }
  .panel-title.main {
    font-size: 18px;
    font-weight: bold;
    color: #303133;
    margin-bottom: 8px;
  }
  .main-form .el-form-item__label {
    font-weight: bold;
    color: #606266;
  }
  .main-divider {
    margin: 18px 0 12px 0;
    border-top: 2px solid #e4e7ed;
  }
  .el-collapse {
    margin-bottom: 12px;
    background: #fafbfc;
    border-radius: 6px;
    border: 1px solid #f0f0f0;
    box-shadow: none;
  }
  .el-collapse-item__header {
    background: #fafbfc !important;
    color: #b1b3b8 !important;
    font-size: 15px !important;
    font-weight: 500;
    padding-left: 8px !important;
    min-height: 38px;
    border-bottom: 1px solid #f0f0f0;
    display: flex;
    align-items: center;
  }
  .el-collapse-item__arrow {
    color: #b1b3b8 !important;
    font-size: 16px !important;
  }
  .el-collapse-item__content {
    background: #fcfcfd;
    font-size: 13px;
    color: #a8abb2;
    padding: 10px 16px 10px 16px !important;
  }
  .sub-title {
    font-size: 15px;
    color: #909399;
    font-weight: 500;
    margin-bottom: 8px;
  }
  .sub-form .el-form-item {
    margin-bottom: 10px;
  }
  .sub-form .el-form-item__label {
    color: #b1b3b8;
    font-size: 13px;
  }
  .sub-form .el-input, .sub-form .el-input-number {
    font-size: 13px;
  }
  .main-form .el-form-item__label,
  .sub-form .el-form-item__label {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    min-width: 120px;
    padding-right: 8px;
    line-height: 32px;
  }
  .main-form .el-input,
  .sub-form .el-input,
  .sub-form .el-input-number {
    width: 100%;
  }
  .assignee-row {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
  }
  .assignee-values {
    margin-left: 8px;
    flex: 1;
  }
  .empty-selected {
    color: #bbb;
    margin-left: 8px;
  }
  .assignee-user-item {
    display: inline-flex;
    align-items: center;
    background: #fff;
    border-radius: 4px;
    padding: 2px 6px;
    margin-right: 6px;
    margin-bottom: 4px;
    box-shadow: 0 1px 2px #eee;
  }
  .assignee-user-name {
    font-weight: 500;
    font-size: 14px;
    color: #333;
    margin-right: 4px;
  }
  .assignee-user-account {
    color: #888;
    font-size: 12px;
    margin-right: 4px;
  }
  </style>
